package com.xframe.domain.views.builder;

import cn.hutool.json.JSONUtil;
import com.xframe.domain.emnus.Constant;
import com.xframe.domain.emnus.PublicFieldEnum;
import com.xframe.domain.emnus.XDelFlag;
import com.xframe.domain.role.IUserCredentials;
import com.xframe.domain.sys.SysModel;
import com.xframe.domain.sys.SysModelAttr;
import com.xframe.domain.sys.SysModelConfig;
import com.xframe.domain.views.IModelConfigBuilder;
import com.xframe.xdal.core.constant.MappingConstants;
import com.xframe.xdal.core.model.mapping.IRelation;
import com.xframe.xdal.core.serialize.JsonModel;
import com.xframe.xdal.core.util.StringUtil;
import lombok.extern.log4j.Log4j2;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 创建被导出使用的模型配置(export)
 * @ClassName: ModelByExportConfigBuilder
 * @Author: xufeng
 * @CreateTime: 2023/12/06
 **/
@Log4j2
public class ModelByExportConfigBuilder implements IModelConfigBuilder {

    static final String CONFIG_TYPE = "ser";
    static final String CN_LANGUAGE = "cn";
    static final String EN_LANGUAGE = "en";
    static final String DEL_PROCCLASS = "com.xframe.xdal.core.serialize.proc.DelFlagSerProc";
    static final String DATE_PROCCLASS = "com.xframe.xdal.core.serialize.proc.DataTimeSerProc";
    static final String DATE_PROCCLASS_ARGS = "yyyy-MM-dd HH:mm:ss";
    static final String EXPORT = "export";
    static final String REF = "exportRef";
    @Override
    public List<SysModelConfig> builder(SysModel sysModel, IUserCredentials userCredentials) {
        List<SysModelConfig> sysModelConfigs = new ArrayList<>();
        SysModelConfig modelCnConfig = SysModelConfigCreate(sysModel,userCredentials,CN_LANGUAGE);
        SysModelConfig modelEnConfig = SysModelConfigCreate(sysModel,userCredentials,EN_LANGUAGE);

        String json = setSysModelConfigContent(sysModel,userCredentials);
        modelCnConfig.setContent(json);
        modelEnConfig.setContent(json);
        sysModelConfigs.add(modelCnConfig);
        sysModelConfigs.add(modelEnConfig);
        return sysModelConfigs;
    }


    public String setSysModelConfigContent(SysModel sysModel, IUserCredentials userCredentials) {
        List<SysModelAttr> sysModelAttrList = sysModel.getModelAttrList();

        List<SysModelAttr> mainAttrs = findMainAttr(sysModelAttrList);

        List<JsonModel> jsonModelList = new ArrayList<>();
        for(SysModelAttr modelAttr : mainAttrs){
            // 判断是不是引用字段
            IRelation relation = findRefAttr(modelAttr,sysModel);
            if(relation == null) {
                JsonModel jsonModel = new JsonModel();
                jsonModel.setName(modelAttr.getAttrName());
                jsonModel.setMapName(modelAttr.getAttrName());
                jsonModel.setRefModelCode(StringUtil.EMPTY);
                jsonModel.setFlag(StringUtil.EMPTY);
                jsonModel.setProcClass(StringUtil.EMPTY);
                jsonModel.setClassArgs(StringUtil.EMPTY);
                jsonModel.setHeader(modelAttr.getDesc());

                String attrType = modelAttr.getType();

                if (attrType.equals(java.util.Date.class.getName())) {
                    jsonModel.setProcClass(DATE_PROCCLASS);
                    jsonModel.setClassArgs(DATE_PROCCLASS_ARGS);
                }
                if(modelAttr.getAttrName().equals("status")){
                    // 状态
                    jsonModel.setProcClass("com.xframe.xdal.core.serialize.proc.StatusFlagProc");
                    //jsonModel.setClassArgs(StringUtil.EMPTY);
                }
                jsonModelList.add(jsonModel);
            }
        }
        List<IRelation> relationList = sysModel.getBelongsToMappingList();
        for(IRelation relation : relationList){
            JsonModel jsonModel = new JsonModel();
            jsonModel.setName(relation.getAs());
            jsonModel.setMapName(relation.getAs());
            jsonModel.setRefModelCode(relation.getDataType().getName());
            jsonModel.setRefModelType(MappingConstants.MAPPING_REF_OBJ);
            jsonModel.setFlag(REF);
            jsonModel.setProcClass(StringUtil.EMPTY);
            jsonModel.setClassArgs(StringUtil.EMPTY);
            jsonModelList.add(jsonModel);
        }

        List<SysModelAttr> publicAttr = findPublicAttr(sysModelAttrList);
        for(SysModelAttr modelAttr : publicAttr) {

            JsonModel jsonModel = new JsonModel();
            jsonModel.setName(modelAttr.getAttrName());
            jsonModel.setMapName(modelAttr.getAttrName());
            jsonModel.setRefModelCode(StringUtil.EMPTY);
            jsonModel.setFlag(StringUtil.EMPTY);
            jsonModel.setProcClass(StringUtil.EMPTY);
            jsonModel.setClassArgs(StringUtil.EMPTY);
            jsonModel.setHeader(modelAttr.getDesc());

            String attrType = modelAttr.getType();

            if (attrType.equals(java.util.Date.class.getName())) {
                jsonModel.setProcClass(DATE_PROCCLASS);
                jsonModel.setClassArgs(DATE_PROCCLASS_ARGS);
            }
            if(modelAttr.getAttrName().equals(PublicFieldEnum.DEL_FLAG.getValue())){
                // 删除标记
                jsonModel.setProcClass(DEL_PROCCLASS);
                //jsonModel.setClassArgs(StringUtil.EMPTY);
            }
            jsonModelList.add(jsonModel);

        }
        return JSONUtil.toJsonStr(jsonModelList);

    }

    protected IRelation findRefAttr(SysModelAttr modelAttr, SysModel sysModel){
        List<IRelation> relationList = sysModel.getBelongsToMappingList();
        if(relationList == null || relationList.size() == 0){
            return null;
        }
        for(IRelation relation : relationList){
            if(relation.getForeignKey().equals(modelAttr.getAttrName())){
                return relation;
            }
        }
        return null;
    }

    protected SysModelConfig SysModelConfigCreate(SysModel sysModel, IUserCredentials userCredentials,String language){
        SysModelConfig modelConfig = new SysModelConfig();
        modelConfig.setConfigType(CONFIG_TYPE);
        modelConfig.setModelCode(sysModel.getModelCode());
        modelConfig.setSystemFlag(Constant.DEF_SYSTEMFLAG);
        modelConfig.setLanguage(language);
        modelConfig.setQueryKey(EXPORT);
        modelConfig.setVer(Constant.DEF_VER);
        modelConfig.setBaseAttrVal(userCredentials);
        modelConfig.setDelFlag(XDelFlag.getDefFlag());
        return modelConfig;
    }

    public static List<SysModelAttr> findMainAttr(List<SysModelAttr> modelAttrList){
        List<SysModelAttr> mainAttrs = new ArrayList<>();
        if(modelAttrList == null){
            return mainAttrs;
        }

        for(SysModelAttr modelAttr : modelAttrList){
            if(modelAttr.getPkFlag().equals("Y") || PublicFieldEnum.isPublicField(modelAttr.getAttrName())){
                continue;
            }
            mainAttrs.add(modelAttr);
        }
        return mainAttrs;
    }

    public static List<SysModelAttr> findPublicAttr(List<SysModelAttr> modelAttrList){
        List<SysModelAttr> publicAttr = new ArrayList<>();
        if(modelAttrList == null){
            return publicAttr;
        }
        for(SysModelAttr modelAttr : modelAttrList){
            if(PublicFieldEnum.isPublicField(modelAttr.getAttrName())){
                if(!modelAttr.getVersionFlag()) {
                    publicAttr.add(modelAttr);
                }
            }
        }
        return publicAttr;
    }
}
